Skip to content

Version Packages#709

Open
daangnbot wants to merge 1 commit intomainfrom
changeset-release/main
Open

Version Packages#709
daangnbot wants to merge 1 commit intomainfrom
changeset-release/main

Conversation

@daangnbot
Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@stackflow/core@1.4.0

Minor Changes

  • cef9c62: Add optional stepContext.path?: string to StepPushedEvent and StepReplacedEvent (purely additive, no breaking change). @stackflow/plugin-history-sync uses this to preserve encode-output URLs through the store across every step navigation path — including popstate forward across step boundaries — instead of relying on plugin-internal state.

    This addresses three regressions surfaced in PR review:

    1. encode output not in history.location — post-effect hooks (onPushed / onReplaced / onStepPushed / onStepReplaced / onInit) called template.fillWithoutEncode(activity.params) against the post-coercion strings, skipping encode and writing coerced values into the URL. Now they read the encoded URL pre-computed in pre-effect hooks (activityContext.path / stepContext.path), with fillWithoutEncode as a defensive fallback only.
    2. encode called with coerced strings on popstate forward re-push — the popstate isForward and isStepForward branches reconstructed push events without preserving activityContext / stepContext, causing onBeforePush / onBeforeStepPush to call template.fill with already-coerced strings. Now those branches pass activityContext: targetActivity.context / stepContext: targetStep.context, and the pre-effect hooks short-circuit when the path is already present ("path" in actionParams.activityContext).
    3. Test gap: path(history.location) was never asserted under non-identity encode — every existing test asserted activity.context.path only. Added 15 new tests asserting the URL surface under non-identity encode, including popstate-forward across activity AND step boundaries, defaultHistory ancestor URLs, SSR replay, and replace-with-active-steps.

@stackflow/plugin-history-sync@1.11.0

Minor Changes

  • cef9c62: Coerce activity/step params to string | undefined at the plugin boundary.

    Before this change, push("X", { visible: true }) would store the boolean true in the core store while URL-arrival parsed the same URL as { visible: "true" }, so useActivityParams<K>() returned different runtime types depending on how the user reached the activity. This PR coerces non-string values to strings inside plugin-history-sync's onBeforePush / onBeforeReplace / onBeforeStepPush / onBeforeStepReplace hooks (after encode consumes the typed params to build the URL), and on the decode-path in overrideInitialEvents, so the core store always contains { [key: string]: string | undefined }. encode still receives the typed params U from template.fill. Post-effect hooks (onPushed, onReplaced, onStepPushed, onStepReplaced, onInit) now use the new fillWithoutEncode to avoid re-running encode on already-coerced store values.

    This is a behavioral change for consumers that relied on internal push preserving non-string values in the store (a pre-existing divergence from URL-arrival behavior). See the docs update for the migration note.

    Migration notes:

    • If you authored a decode hook that returns typed values (e.g. decode: (p) => ({ count: Number(p.count) })), those return values are now coerced back to strings in the store to match the declared ActivityBaseParams contract. Move runtime type coercion to the usage site (Number(useActivityParams().count)).
    • If your app registers a plugin AFTER historySyncPlugin in the plugins array and that plugin re-injects typed values via overrideActionParams, those values will NOT be coerced by this plugin. Register historySyncPlugin last among plugins that mutate activityParams to preserve the string-only invariant.
    • Cross-deploy hydration: when a user reloads on a deploy that includes this fix after a previous deploy serialized typed values into history.state, the params are coerced to strings at hydration time inside the parseState early-return. No consumer change required — the post-fix runtime contract (useActivityParams() returns string | undefined) holds across version boundaries.

Patch Changes

  • cef9c62: Add optional stepContext.path?: string to StepPushedEvent and StepReplacedEvent (purely additive, no breaking change). @stackflow/plugin-history-sync uses this to preserve encode-output URLs through the store across every step navigation path — including popstate forward across step boundaries — instead of relying on plugin-internal state.

    This addresses three regressions surfaced in PR review:

    1. encode output not in history.location — post-effect hooks (onPushed / onReplaced / onStepPushed / onStepReplaced / onInit) called template.fillWithoutEncode(activity.params) against the post-coercion strings, skipping encode and writing coerced values into the URL. Now they read the encoded URL pre-computed in pre-effect hooks (activityContext.path / stepContext.path), with fillWithoutEncode as a defensive fallback only.
    2. encode called with coerced strings on popstate forward re-push — the popstate isForward and isStepForward branches reconstructed push events without preserving activityContext / stepContext, causing onBeforePush / onBeforeStepPush to call template.fill with already-coerced strings. Now those branches pass activityContext: targetActivity.context / stepContext: targetStep.context, and the pre-effect hooks short-circuit when the path is already present ("path" in actionParams.activityContext).
    3. Test gap: path(history.location) was never asserted under non-identity encode — every existing test asserted activity.context.path only. Added 15 new tests asserting the URL surface under non-identity encode, including popstate-forward across activity AND step boundaries, defaultHistory ancestor URLs, SSR replay, and replace-with-active-steps.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 8, 2026

Deploying stackflow-demo with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1b30963
Status:🚫  Build failed.

View logs

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 8, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
stackflow-docs 1b30963 May 08 2026, 05:50 AM

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added optional path field to step navigation events for enhanced URL preservation during navigation.
  • Bug Fixes

    • Fixed URL encoding preservation across step-based navigation and forward popstate behavior.
    • Improved consistency of parameter handling across navigation paths.
  • Tests

    • Expanded test coverage for custom encoding scenarios and complex navigation flows.

Walkthrough

This PR releases coordinated versions of @stackflow/core (1.4.0) and @stackflow/plugin-history-sync (1.11.0), adding an optional stepContext.path field to preserve encoded URLs across step navigation and documenting param coercion behavior at plugin boundaries.

Changes

History Sync Plugin Release

Layer / File(s) Summary
Type/API Contract
.changeset/step-context-path.md, core/CHANGELOG.md
New optional stepContext.path?: string field added to StepPushedEvent and StepReplacedEvent to carry pre-computed encoded URL paths through step navigation.
Plugin Behavior Changes
.changeset/coerce-activity-params-to-string.md
Activity/step params coerced to string | undefined during onBeforePush/onBeforeReplace/onBeforeStepPush/onBeforeStepReplace and decode paths; post-effect hooks adjusted to avoid re-encoding coerced values.
Package Versioning
core/package.json, extensions/plugin-history-sync/package.json
Core bumped to 1.4.0, plugin bumped to 1.11.0; plugin dev dependency constraint updated to @stackflow/core@^1.4.0.
Release Documentation
extensions/plugin-history-sync/CHANGELOG.md, core/CHANGELOG.md, docs/components/ChangelogContent.mdx
Release notes documenting param coercion behavior, migration notes for custom decode hooks and plugin ordering, URL path preservation fixes across popstate scenarios, and expanded test coverage for non-identity encode.

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'Version Packages' is a generic, standard label for automated release PRs opened by the Changesets action, accurately reflecting the changeset-driven release workflow.
Description check ✅ Passed The pull request description directly relates to the changeset by documenting the specific changes, behavioral fixes, and migration notes for the two released packages and their versions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch changeset-release/main

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
extensions/plugin-history-sync/package.json (1)

72-78: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

peerDependencies["@stackflow/core"] minimum version must be bumped to ^1.4.0

The plugin 1.11.0 reads and writes stepContext.path — a field introduced on StepPushedEvent/StepReplacedEvent in @stackflow/core@1.4.0. The current peer range (^1.1.0-canary.0) allows a consumer to resolve @stackflow/core@1.3.x, which satisfies npm's semver resolution. Under that older core:

  • TypeScript will error because stepContext.path does not exist on the event types.
  • At runtime the property is silently ignored by the core store, so the URL-encoding regression fix (item 2 in the changelog) is silently defeated.
🔧 Proposed fix
   "peerDependencies": {
     "@stackflow/config": "^1.0.1-canary.0",
-    "@stackflow/core": "^1.1.0-canary.0",
+    "@stackflow/core": "^1.4.0",
     "@stackflow/react": "^1.3.2-canary.0",
     "@types/react": ">=16.8.0",
     "react": ">=16.8.0"
   },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/plugin-history-sync/package.json` around lines 72 - 78, Update the
peerDependencies entry for `@stackflow/core` in package.json to require at least
version ^1.4.0 (replace the existing "^1.1.0-canary.0" range) so the plugin can
rely on StepPushedEvent/StepReplacedEvent having stepContext.path; modify the
peerDependencies block in the extensions/plugin-history-sync package.json
accordingly to prevent consumers from resolving older `@stackflow/core` versions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@extensions/plugin-history-sync/package.json`:
- Around line 72-78: Update the peerDependencies entry for `@stackflow/core` in
package.json to require at least version ^1.4.0 (replace the existing
"^1.1.0-canary.0" range) so the plugin can rely on
StepPushedEvent/StepReplacedEvent having stepContext.path; modify the
peerDependencies block in the extensions/plugin-history-sync package.json
accordingly to prevent consumers from resolving older `@stackflow/core` versions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 78fe55a7-0578-4f73-8b5b-7af3bf3f7d45

📥 Commits

Reviewing files that changed from the base of the PR and between cef9c62 and 1b30963.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • .changeset/coerce-activity-params-to-string.md
  • .changeset/step-context-path.md
  • core/CHANGELOG.md
  • core/package.json
  • docs/components/ChangelogContent.mdx
  • extensions/plugin-history-sync/CHANGELOG.md
  • extensions/plugin-history-sync/package.json
💤 Files with no reviewable changes (2)
  • .changeset/coerce-activity-params-to-string.md
  • .changeset/step-context-path.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant